package com.dingding.special.user.driver.dao.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.dingding.common.core.base.dao.impl.BaseDaoImpl;
import com.dingding.common.core.base.daox.IBaseDaoX;
import com.dingding.common.core.base.daox.ICriteriaBaseDao;
import com.dingding.common.core.base.daox.ISQLBaseDao;
import com.dingding.common.core.beans.Userorder;
import com.dingding.common.core.beans.special.Specialuserlogin;
import com.dingding.common.core.beans.special.Specialuserposition;
import com.dingding.common.core.beans.special.Specialuservehicleinfo;
import com.dingding.common.core.beans.special.Specialvehicleaudit;
import com.dingding.common.core.beans.special.Userspecialorder;
import com.dingding.common.core.beans.special.UserspecialorderT;
import com.dingding.common.core.util.DateFormatUtil;
import com.dingding.common.core.util.StringUtils;
import com.dingding.common.core.util.ToolUtil;
import com.dingding.common.core.util.oss.upload.ImageUpload;
import com.dingding.special.common.exception.bussiness.BizExpEnum;
import com.dingding.special.common.exception.bussiness.BussinessException;
import com.dingding.special.common.exception.server.ServerException;
import com.dingding.special.common.exception.server.ServerExpEnum;
import com.dingding.special.user.driver.dao.IDriverUserDao;
import com.dingding.special.user.driver.dto.driverauth.ReqSpecialDriverAuth;
import com.dingding.special.user.driver.dto.onlinedriver.OLineDriverDto;
import com.dingding.special.user.driver.enums.CarAuthStatus;
import com.dingding.special.user.driver.status.OutCarStatus;

@SuppressWarnings("all")
@Component("driverUserDao")
public class DriverUserDaoImpl extends BaseDaoImpl<Specialuserposition> implements IDriverUserDao {

	Logger log = Logger.getLogger(this.getClass());
	
	@Resource(name = "baseDaoX")
	private IBaseDaoX baseDaoX;
	
	@Resource(name = "SQLBaseDao")
	private ISQLBaseDao isqlBaseDao;
	
	@Resource(name = "criteriaBaseDao")
	private ICriteriaBaseDao criteriaBaseDao;
	
	@Override
	public double getTodayDrivingHours(String userId){
		
		String today = DateFormatUtil.yyyy_MM_dd();
		today = today + "%";
		List<Specialuserposition> list = null;
		try {
			list = (List<Specialuserposition>) super.listSqlFreeObject(
					"select * from specialuserposition where userId = ? and outwardRunTime like ?", Specialuserposition.class, userId,today);
		} catch (Exception e) {
			log.error("查询司机当天在线时间出错！DriverUserDaoImpl：getTodayDrivingHours()",e);
			throw new ServerException(ServerExpEnum.SERVER_DATABASE_EXCEPTION);
		}
		
		if(list == null || list.size() == 0){
			return 0;
		}else{
			Specialuserposition specialuserposition = list.get(0);
			BigDecimal onlinDuration = specialuserposition.getOnlineDuration();
			if(specialuserposition.getSupStatus() == OutCarStatus.UN_HANDLING.getCode()){
				return specialuserposition.getOnlineDuration().doubleValue();
			}else{
				Date date = specialuserposition.getOutwardRunTime();
				int newOnLine = DateFormatUtil.getDateTimeDifference(date, new Date());
				BigDecimal b1 = new BigDecimal(newOnLine);
				b1 = b1.divide(new BigDecimal(60),1);
				onlinDuration = onlinDuration.add(b1);
				return onlinDuration.doubleValue(); 
			}
		}
	}

	@Override
	public List<Userspecialorder> getTodayAllDealOrder(String userId) {
		
		List<Userspecialorder> dealOrders = null;
		//今日时间字符串
		String todayStr = DateFormatUtil.yyyy_MM_dd();
		try {
			dealOrders = (List<Userspecialorder>) super.listSqlFreeObject(
					"select * from userspecialorder where grabOrderUserId = ? and date_format(createTime,'%Y-%m-%d') = ?", Userspecialorder.class,userId,todayStr);
		} catch (Exception e) {
			log.error("获取司机当天所有已成交订单出错！DriverUserDaoImpl：getTodayAllDealOrder()",e);
			throw new ServerException(ServerExpEnum.SERVER_DATABASE_EXCEPTION);
		}
		
		if(dealOrders == null || dealOrders.size() == 0){
			return new ArrayList<Userspecialorder>();
		}else{
			return dealOrders;
		}
	}
	
	/**
	 * 
	 * @Title: getTodayAllDealTaxiOrder 
	 * @Description: 获取出租车司机当日成交订单
	 * @param userId 用户
	 * @author YHQ 
	 * @since V2.5.6
	 * @return List<Userorder>    返回类型
	 * 
	 */
	@Override
	public List<Userorder> getTodayAllDealTaxiOrder(String userId) {
		
		List<Userorder> dealOrders = null;
		String currentDayStr = DateFormatUtil.yyyy_MM_dd();
		try {
			dealOrders = (List<Userorder>) super.listSqlFreeObject(
					"select oid,placeOrderUserId,setOutTime,payCity,startAddress,startLongitude,startLatitude,endAddress,endLongitude,endLatitude,distance,payMoney,alipayMoney,totalMoney,couponMoney,number,redBag,message,payDistance,marker,grabOrderUserId,grabOrderTime,orderStatus,createTime,payTime,cancelTime,endTime,orderType,payType,cancelType,cancelDesc,cancelNumber,isLongDistance,ucId,driverRcvIntegral,psgRcvIntegral,isComment,cancelUserId,isCarShare,setOutCondition,transactionType,publishType,parOrderId from userorder where grabOrderUserId = ? and date_format(createTime,'%Y-%m-%d') = ?",
					Userorder.class,userId,currentDayStr);
		} catch (Exception e) {
			log.error("获取司机当天所有已成交订单出错！DriverUserDaoImpl：getTodayAllDealOrder()",e);
			throw new ServerException(ServerExpEnum.SERVER_DATABASE_EXCEPTION);
		}
		
		if(dealOrders == null || dealOrders.size() == 0){
			return new ArrayList<Userorder>();
		}else{
			return dealOrders;
		}
	}
	
	@Override
	public List<UserspecialorderT> getTodayAllUnDealOrder(String userId) {
		
		List<UserspecialorderT> dealOrders = null;
		try {
			dealOrders = (List<UserspecialorderT>) super.listSqlFreeObject(
					"select * from UserspecialorderT where grabOrderUserId = ? and orderStatus in (1,2,3,4)", UserspecialorderT.class,userId);
		} catch (Exception e) {
			log.error("获取司机当天所有已成交订单出错！DriverUserDaoImpl：getTodayAllDealOrder()",e);
			throw new ServerException(ServerExpEnum.SERVER_DATABASE_EXCEPTION);
		}
		
		if(dealOrders == null || dealOrders.size() == 0){
			return new ArrayList<UserspecialorderT>();
		}else{
			return dealOrders;
		}
	}

	@Override
	public int getOutCarStatus(String userId) {
		
		List<Specialuserposition> list = null;
		try {
			list = (List<Specialuserposition>) super.listSqlFreeObject(
					"select * from specialuserposition where userId = ?", Specialuserposition.class, userId);
		} catch (Exception e) {
			log.error("查询出车状态异常！DriverUserDaoImpl:getOutCarStatus()",e);
			throw new ServerException(ServerExpEnum.SERVER_DATABASE_EXCEPTION);
		}
		
		if(list == null || list.size() == 0){
			return OutCarStatus.UN_HANDLING.getCode();
		}else{
			return list.get(0).getSupStatus();
		}
	}

	@Override
	public List<Userspecialorder> getTodayAllOrders(String userId) {
		
		List<UserspecialorderT> undeals = this.getTodayAllUnDealOrder(userId);
		List<Userspecialorder> deals = this.getTodayAllDealOrder(userId);
		
		for(UserspecialorderT ordert : undeals){
			Userspecialorder order = new Userspecialorder();
			BeanUtils.copyProperties(ordert, order);
			deals.add(order);
		}
		
		return deals;
	}
	
	@Override
	public List<Specialuserposition> getAllCurrentDriversPosition(String cityName) {
		List<Specialuserposition> list = null;
		try {
			list = (List<Specialuserposition>) super.listSqlFreeObject(
					"select * from specialuserposition where currentCity like ? and supStatus = 1", Specialuserposition.class, StringUtils.cityLike(cityName));
		} catch (Exception e) {
			log.error("获取当前全部在线车主时出错！DriverUserDaoImpl : getAllCurrentDriversPosition()",e);
			throw new ServerException(ServerExpEnum.SERVER_DATABASE_EXCEPTION);
		}
		if(list == null){
			return new ArrayList<Specialuserposition>();
		}		
		return list;
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public List<OLineDriverDto> getAllOnlineDrivers(String cityName) {
		List<OLineDriverDto> list = null;
		
		//TODO 从缓存读取所有在线司机的偏好和所有司机的当前位置
		if(list == null){
			try {
				list = (List<OLineDriverDto>) super.listSqlFreeObject(GET_ALL_DRIVERS_PREFER, OLineDriverDto.class, StringUtils.cityLike(cityName));
			} catch (Exception e) {
				log.error("获取当前全部在线车主的偏好时出错！DriverUserDaoImpl : getAllOnlineDrivers()",e);
				throw new ServerException(ServerExpEnum.SERVER_DATABASE_EXCEPTION);
			}
			if(list == null){
				return new ArrayList<OLineDriverDto>();
			}
		}
		
		return list;
	}

	@Override
	@Transactional(readOnly = true)
	public List<OLineDriverDto> getRealTimeOnlineDrivers(String cityName) {
		List<OLineDriverDto> realTime = new ArrayList<OLineDriverDto>();
		List<OLineDriverDto> list = this.getAllOnlineDrivers(cityName);
		for(OLineDriverDto dto : list){
			if(dto.getAppointOrderType() == 1 || dto.getAppointOrderType() == 3)	//1:实时 2:预约 3:全部
				realTime.add(dto);
		}
		return realTime;
	}

	@Override
	@Transactional(readOnly = true)
	public List<OLineDriverDto> getUnRealTimeOnlineDrivers(String cityName) {
		List<OLineDriverDto> realTime = new ArrayList<OLineDriverDto>();
		List<OLineDriverDto> list = this.getAllOnlineDrivers(cityName);
		for(OLineDriverDto dto : list){
			if(dto.getAppointOrderType() == 2 || dto.getAppointOrderType() == 3)	//1:实时 2:预约 3:全部
				realTime.add(dto);
		}
		return realTime;
	}

	@Override
	@Transactional(readOnly = true)
	public Specialuservehicleinfo getSpecialUserVehicleInfo(String userId) {
		
		try {
			Specialuserlogin login = this.baseDaoX.getById(userId, Specialuserlogin.class);
			if(login == null){
				log.error("没有id为" + userId + "的用户！DriverUserDaoImpl：getSpecialUserVehicleInfo()");
				return null;
			}
		} catch (Exception e) {
			log.error("查询用户信息出错！DriverUserDaoImpl：getSpecialUserVehicleInfo()",e);
			throw new ServerException(ServerExpEnum.SERVER_DATABASE_EXCEPTION);
		}
		
		Specialuservehicleinfo specialuservehicleinfo = null;
		List<Specialuservehicleinfo> vlist = null;
		try {
			vlist = (List<Specialuservehicleinfo>) super.listSqlFreeObject(
					"select * from specialuservehicleinfo where userId = ?", Specialuservehicleinfo.class, userId);
		} catch (Exception e) {
			log.error("查询用户的车辆信息出错！DriverUserDaoImpl：getSpecialUserVehicleInfo()",e);
			throw new ServerException(ServerExpEnum.SERVER_DATABASE_EXCEPTION);
		}
		
		if(vlist == null || vlist.size() == 0){
			specialuservehicleinfo = new Specialuservehicleinfo();
			specialuservehicleinfo.setUserId(userId);
			try {
				baseDaoX.save(specialuservehicleinfo);
			} catch (Exception e) {
				log.error("查询用户的车辆信息出错！DriverUserDaoImpl：getSpecialUserVehicleInfo()",e);
				throw new ServerException(ServerExpEnum.SERVER_DATABASE_EXCEPTION);
			}
			return specialuservehicleinfo;
		}else{
			return vlist.get(0);
		}
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public Specialuservehicleinfo saveSpecialUserVehicleInfo(ReqSpecialDriverAuth reqSpecialDriverAuth) {
		
		//判断车牌是否被认证过
		boolean isReg = this.isLisenceIsReg(reqSpecialDriverAuth.getLisencePlate(),reqSpecialDriverAuth.getUserId());
		
		if(isReg == false){
			//获取该用户的车主认证信息
			Specialuservehicleinfo specialuservehicleinfo = this.getSpecialUserVehicleInfo(reqSpecialDriverAuth.getUserId());
			Integer status = specialuservehicleinfo.getSuvStatus();//1：审核中 2：审核通过 3：审核未通过
			if(status == null || (status != 1 && status != 2) || (status == 0)){
				BeanUtils.copyProperties(reqSpecialDriverAuth, specialuservehicleinfo);
				specialuservehicleinfo.setSuvStatus(1);//1：审核中 2：审核通过 3：审核未通过
				specialuservehicleinfo.setSubmitTime(new Date());
				
				//上传图片
				String jszImageName = new ImageUpload().upLoadPicture(reqSpecialDriverAuth.getJszImage());
				String xszImageName = new ImageUpload().upLoadPicture(reqSpecialDriverAuth.getXszImage());
				String vehiImageName = new ImageUpload().upLoadPicture(reqSpecialDriverAuth.getVehicleImage());
				if(ToolUtil.isNotBlank(jszImageName) && ToolUtil.isNotBlank(xszImageName) && ToolUtil.isNotBlank(vehiImageName)){
					//specialuservehicleinfo.setJszImage(jszImageName);
					specialuservehicleinfo.setXszImage(xszImageName);
					specialuservehicleinfo.setVehicleImage(vehiImageName);
					this.baseDaoX.update(specialuservehicleinfo);
					return specialuservehicleinfo;
				}else{
					log.error("上传车辆图片的时候出错！DriverUserDaoImpl : saveSpecialUserVehicleInfo()");
					throw new ServerException(ServerExpEnum.UPLOAD_IMAGE_ERROR);
				}
			}else{
				log.error("用户的审核状态为审核中或审核通过，不能认证！DriverUserDaoImpl : saveSpecialUserVehicleInfo()");
				throw new BussinessException(BizExpEnum.USER_VEHI_CAR_STATUS_ERROR);
			}
		}else{
			log.error("该车辆已经已被其他用户使用！DriverUserDaoImpl : saveSpecialUserVehicleInfo()");
			throw new BussinessException(BizExpEnum.VEHI_IS_BE_REGED);
		}
	}

	@Override
	@Transactional(readOnly = true)
	public boolean isLisenceIsReg(String lisencePlate,String userId) {
		
		List<Specialuservehicleinfo> vlist = null;
		
		try {
			vlist = (List<Specialuservehicleinfo>) super.listSqlFreeObject(
					"select * from specialuservehicleinfo where lisencePlate = ? AND userId != ?", Specialuservehicleinfo.class, lisencePlate,userId);
		} catch (Exception e) {
			log.error("查询车牌号是否被注册过的时候出错！",e);
			throw new ServerException(ServerExpEnum.SERVER_DATABASE_EXCEPTION);
		}
		if(vlist == null || vlist.size() == 0){
			return false;
		}else{
			return true;
		}
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public boolean changeCarAuthStatus(String userId, CarAuthStatus status) {
		
		try {
			Specialuservehicleinfo specialuservehicleinfo = this.criteriaBaseDao.queryCriteriaListUnique(
					Specialuservehicleinfo.class,Restrictions.eq("userId", userId));
			
			if(specialuservehicleinfo != null){
				specialuservehicleinfo.setSuvStatus(status.getCode());
				return true;
			}else{
				throw new BussinessException(BizExpEnum.NOT_FOUND_USERS_VEHICLEINFO);
			}
		} catch (Exception e) {
			log.error("存储审核记录错误！DriverUserDaoImpl ： recordDriverAuth()",e);
			throw new ServerException(ServerExpEnum.SERVER_DATABASE_EXCEPTION);
		}
	}

	@Override
	public void recordDriverAuth(Specialuservehicleinfo vehicleInfo) {
		Specialvehicleaudit audit = new Specialvehicleaudit();
		BeanUtils.copyProperties(vehicleInfo, audit);
		audit.setCreateTime(vehicleInfo.getSubmitTime());
		audit.setSvStatus(vehicleInfo.getSuvStatus());
		audit.setVaId(ToolUtil.getUid());
		try {
			this.baseDaoX.save(audit);
		} catch (Exception e) {
			log.error("存储审核记录错误！DriverUserDaoImpl ： recordDriverAuth()",e);
			throw new ServerException(ServerExpEnum.SERVER_DATABASE_EXCEPTION);
		}
	}

	@Override
	@Transactional(readOnly = true)
	public List<OLineDriverDto> getAllOnlineTaxiDrivers(String city) {
		List<OLineDriverDto> realTime = null;
		try {
			realTime = this.isqlBaseDao.listSqlToCustomBean(
					OLineDriverDto.class, ALL_ONLINE_TAXIS_BY_CITY, StringUtils.cityLike(city));
		} catch (Exception e) {
			log.error("查询所有的在线出租车司机时出错！DriverUserDaoImpl : getAllOnlineTaxiDrivers()",e);
			realTime = new ArrayList<OLineDriverDto>();
		}
		return realTime;
	}
}
